import { AbstractMesh } from '@babylonjs/core/Meshes/abstractMesh';
import { CreateHandleTo, IHandle, RemoveHandle } from '../../../data/data-handle';


/**
 * 选择配置抽象类
 */
abstract class AbstractSelectConfig<T>{

    private _selectHandles: IHandle<T>[] = [];
    private _unselectHandles: IHandle<T>[] = [];

    /**
     * 测试目标对象是否适合当前配置
     * @param target 目标对象
     */
    public abstract test(target: T): boolean;

    /**
     * 比较目标对象是否相同
     * @param a 目标对象1
     * @param b 目标对象2
     */
    public abstract compare(a: T, b: T): boolean;

    /**
     * 获取目标对象的作用网格
     * @param target 目标对象
     */
    public abstract meshes(target: T): AbstractMesh[];

    /**
     * 检测目标网格是否属于目标对象
     * @param mesh 目标网格
     * @param target 目标对象
     * @returns 层级深度
     */
    public abstract isMeshOfTarget(mesh: AbstractMesh, target: T): number;

    /**
     * 添加选择时的回调函数对象
     * @param func 回调函数
     * @returns 回调函数对象
     */
    public onSelect(func: { (target: T): void }): IHandle<T> {
        return CreateHandleTo(func, this._selectHandles);
    }

    /**
     * 移除选择时的回调函数对象
     * @param handle 回调函数对象或其id
     */
    public removeSelectHandle(handle: IHandle<T> | number): void {
        RemoveHandle(handle, this._selectHandles);
    }

    /**
     * 设置选择对象
     * @param target 目标对象
     */
    public setSelected(target: T): void {
        this._selectHandles.forEach(handle => handle.callback(target));
    }

    /**
     * 添加取消选择时的回调函数对象
     * @param func 回调函数
     * @returns 回调函数对象
     */
    public onUnselect(func: { (target: T): void }): IHandle<T> {
        return CreateHandleTo(func, this._unselectHandles);
    }

    /**
     * 移除取消选择时的回调函数对象
     * @param handle 回调函数对象
     */
    public removeUnselectHandle(handle: IHandle<T>): void {
        RemoveHandle(handle, this._unselectHandles);
    }

    /**
     * 设置取消选择对象
     * @param target 目标对象
     */
    public setUnselected(target: T): void {
        this._unselectHandles.forEach(handle => handle.callback(target));
    }

}


export { AbstractSelectConfig };